#include <stdio.h>

#define ctoi(c)      (c - '0')
#define check_num(c) (ctoi(c) >= 0 && ctoi(c) <= 9)
#define UP_LIMIT     (2147483647)
#define DOWN_LIMIT   (-2147483648)

int myAtoi(char *s) {
    char *p  = s;
    int sign = 1;
    int val  = 0;

    int cnt        = 0;
    int start_flag = 0;
    while (*p) {
        if (!check_num(*p)) {
            if (start_flag)
                break;
            else {
                if (*p == '-') {
                    sign = -1;
                    p++;
                    start_flag = 1;
                    continue;
                } else if (*p == '+') {
                    sign = 1;
                    p++;
                    start_flag = 1;
                    continue;
                } else if (*p == ' ') {
                    p++;
                    continue;
                } else {
                    break;
                }
            }
        }

        if (val != 0 && (DOWN_LIMIT / val == 0 || UP_LIMIT / val == 0)) {
            return sign == 1 ? UP_LIMIT : DOWN_LIMIT;
        }

        if (UP_LIMIT / 10 < val * sign || DOWN_LIMIT / 10 > val * sign) {
            return sign == 1 ? UP_LIMIT : DOWN_LIMIT;
        }

        if (UP_LIMIT / 10 == val * sign && ctoi(*p) > 7) {
            return UP_LIMIT;
        }

        if (DOWN_LIMIT / 10 == val * sign && ctoi(*p) > 7) {
            return DOWN_LIMIT;
        }
        val        = val * 10 + ctoi(*p);
        start_flag = 1;

        p++;
    }
    return val * sign;
}

int main(void) {
    printf("字符串转整数(atoi)\n "
           "这个题解法比较常规，就是需要注意各种特殊符号导致的状态不同\n\n");

#define STR_MAX_LEN 20
    char test[][STR_MAX_LEN] = {
        " -100",      "01010 ",        " -2147483648 ",       "1337c0d3",
        "-133-7c0d3", "words and 987", "0000000000012345678", "0-1",
        "-2147483648"};
    printf("test case num: %d\n", sizeof(test) / STR_MAX_LEN);
    for (int i = 0; i < sizeof(test) / STR_MAX_LEN; i++)
        printf("%d %s: %d\n", i, test[i], myAtoi(test[i]));
    return 0;
}